package example;

import java.util.concurrent.locks.StampedLock;

/**
 * @author dengzhiyuan
 * @version 1.0
 * @describe
 * @time 2023/3/19 22:17
 */
public class StampedLockExample {

//    long readLock(): 获取一个悲观读锁，如果当前没有线程持有写锁，则立即返回锁的版本号，否则当前线程阻塞等待写锁释放。
//    long tryReadLock(): 尝试获取一个悲观读锁，如果当前没有线程持有写锁，则立即返回锁的版本号，否则返回 0。
//    long writeLock(): 获取一个写锁，如果当前没有线程持有读锁或写锁，则立即返回锁的版本号，否则当前线程阻塞等待锁的释放。
//    long tryWriteLock(): 尝试获取一个写锁，如果当前没有线程持有读锁或写锁，则立即返回锁的版本号，否则返回 0。
//    void unlockRead(long stamp): 释放一个悲观读锁，将锁的版本号作为参数传入。
//    void unlockWrite(long stamp): 释放一个写锁，将锁的版本号作为参数传入。
//    long tryOptimisticRead(): 尝试获取一个乐观读锁，返回一个非零的版本号，如果当前没有线程持有写锁，则获取成功，否则返回 0。
//    boolean validate(long stamp): 检查当前乐观读锁是否有效，传入上一次获取乐观读锁时的版本号，如果当前没有写锁被持有，则返回 true。
//    需要注意的是，在使用 StampedLock 时，需要遵循乐观读锁、悲观读锁、写锁的获取顺序，避免死锁的发生。另外，StampedLock 不支持重入，如果在获取锁的过程中再次获取同一种锁，会导致线程阻塞。

    private int count = 0 ;

    private final StampedLock lock = new StampedLock();

    public void increment(){
        //获取写锁
        long writeLock = lock.writeLock();
        try {
            count++;
        }finally {
            //释放写锁
            lock.unlockWrite(writeLock);
        }
    }

    public int getCount(){
        long optimisticRead = lock.tryOptimisticRead();
        int value = count;
        if(!lock.validate(optimisticRead)){
            //获取读锁
            long readLock = lock.readLock();
            try {
                value = count;
            }finally {
                lock.unlockRead(readLock);
            }
        }
        return value;
    }

    public static void main(String[] args) {
        StampedLockExample lockExample = new StampedLockExample();
        lockExample.increment();
        int count1 = lockExample.getCount();
        System.out.println(count1);

    }



}
